package com.yanyeori.framework.core.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.yanyeori.framework.core.constant.BaseConstant;
import com.yanyeori.framework.core.constant.BaseErrorCode;
import com.yanyeori.framework.core.context.TraceContext;
import com.yanyeori.framework.core.util.StringUtil;

import java.io.Serializable;
import java.util.Date;

/**
 * 统一交互数据包装对象
 *
 * @author chenkuan
 * @since 2020/7/30
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class WebResponse<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    private static final Integer SUCCESS = 0;

    private Integer code;
    private String message;
    private T data;
    @JsonFormat(pattern = BaseConstant.FORMAT_DATETIME)
    private Date time;

    //链路id
    private String traceId;

    public WebResponse() {
        this(SUCCESS, "Success");
    }

    public WebResponse(int code, String message, Object... params) {
        this.code(code).message(message, params);
        this.time = new Date();
        this.traceId = TraceContext.get(true).getTraceId();
    }

    public WebResponse<T> data(T data) {
        this.data = data;
        return this;
    }

    public WebResponse<T> code(int code) {
        this.setCode(code);
        return this;
    }

    public WebResponse<T> message(String message, Object... params) {
        this.setMessage(StringUtil.format(message, params));
        return this;
    }

    public static <T> WebResponse<T> ok() {
        return new WebResponse<T>();
    }

    public static <T> WebResponse<T> ok(T data) {
        return new WebResponse<T>().data(data);
    }

    public static <T> WebResponse<T> fail(String message, Object... params) {
        WebResponse<T> resp = new WebResponse<T>();
        resp.code(500);
        resp.message(message, params);
        return resp;
    }

    public static <T> WebResponse<T> fail(int code, String message, Object... params) {
        WebResponse<T> resp = new WebResponse<T>();
        resp.code(SUCCESS.equals(code) ? 500 : code);
        resp.message(message, params);
        return resp;
    }

    public static <T> WebResponse<T> fail(BaseErrorCode baseErrorCode, Object... params) {
        WebResponse<T> resp = new WebResponse<T>();
        resp.code(SUCCESS.equals(baseErrorCode.getCode()) ? 500 : baseErrorCode.getCode());
        resp.message(baseErrorCode.getMsg(), params);
        return resp;
    }

    public boolean isSuccess() {
        return SUCCESS.equals(this.code);
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Date getTime() {
        return time;
    }

    public void setTime(Date time) {
        this.time = time;
    }

    public String getTraceId() {
        return traceId;
    }

    public void setTraceId(String traceId) {
        this.traceId = traceId;
    }

    @Override
    public String toString() {
        return "WebResponse{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", data=" + data +
                ", time=" + time +
                ", traceId=" + traceId +
                '}';
    }
}
